#include <stdio.h>
#include <windows.h>	// SetConsoleTextAttribute
#include <conio.h>		// getch()

#include "v.h"
#include "ll.h"

#define BASE_COLOR	(FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE)

void safePrint(char c)
{
	int color = BASE_COLOR;
	switch(c)
	{
		// null terminator (0)
	case '\0':	color = BACKGROUND_BLUE;	c = '0';	break;
		// alarm (7)
	case '\a':	color = FOREGROUND_RED;		c = 'a';	break;
		// backspace (8)
	case '\b':	color = FOREGROUND_BLUE;	c = 'b';	break;
		// tab (9)
	case '\t':	color = FOREGROUND_GREEN;	c = 't';	break;
		// new line (10)
	case '\n':	color = FOREGROUND_RED|FOREGROUND_INTENSITY;		c = 'n';	break;
		// carriage return (13)
	case '\r':	color = FOREGROUND_RED;		c = 'r';	break;
		// EOF
	case -1:	color = FOREGROUND_BLUE;	c = '-';	break;
	}
	SetConsoleTextAttribute(
		GetStdHandle(STD_OUTPUT_HANDLE),
		color);
	putchar(c);
	SetConsoleTextAttribute(
		GetStdHandle(STD_OUTPUT_HANDLE),
		BASE_COLOR);
}

int main(int argc, char ** argv)
{
	V v;
	v.add(5);
	LinkedList list;
	list.add(5);
	list.add(25);
	list.add(35);
	list.add(45);
	list.add(55);
	list.add(65);
	int someVariable = 5;

	V history;

	// reference and de-reference unary operator
	*(&(*(&someVariable))) = 12;

	// mean buffer corruption
	//*((&someVariable)+1) = 0;

	printf("size:%d   address:%d, 0x%08x  value:%d\n",
		sizeof(someVariable), 
		&someVariable, 
		&someVariable, 
		someVariable);

//	// print all the ascii values
//	for(int i = 0; i < 256; ++i)
//	{
//		printf("%d [%c]\n", i, i);
//	}

	// prints out memory around someVariable
	char * ptr = (char*)&someVariable;//v.getRawData();
	int * iPtr;
	// intialize
	// input
	// update
	// draw
	// release

	// main state variable for the game
	bool running = true;
	int input;
	while(running)
	{
		// draw
		// reset the cursor to 0,0 (start drawing at the top)
		COORD p = {0,0};
		SetConsoleCursorPosition(
			GetStdHandle(STD_OUTPUT_HANDLE), p);
		// draw the memory
		for(int i = 0; i < 1600; ++i)
		{
			safePrint(*(ptr+i));
		}
		printf("loc : 0x%08x\n", ptr);
		printf("byte: %12d\n", *ptr);
		iPtr = (int*)ptr;
		printf("int : %12d\n", *iPtr);
		printf("hex : 0x%08x\n", *iPtr);
		// input
		input = _getch();
		// update
		switch(input)
		{
		case 'w':	ptr -= 80;	break;
		case 'a':	ptr -= 1;	break;
		case 's':	ptr += 80;	break;
		case 'd':	ptr += 1;	break;
		case 'q':	running = false;	break;
		case '\n':	case '\r':
			{
				// get the place we're porting to before it changes...
				int whatThePointerPointsTo = *iPtr;
				int whereIam = (int)ptr;
				history.add(whereIam);
				ptr = (char*)whatThePointerPointsTo;
			}
			break;
		case '\b':
			if(history.size() > 0)
			{
				int whereIwas = history.get(history.size()-1);
				ptr = (char*)whereIwas;
				history.setSize(history.size()-1);
			}
			break;
		}
	}
	return 0;
}